import frida
import os
import sys
from pathlib import Path


def read_agent_js_source(name: str = "_agent.js"):
    with open(name, "r", encoding="utf-8") as f:
        return f.read()


def on_message(message, data):
    print(message)
    pass


def build_agent_js():
    _agent_path = Path("_agent.js")
    if _agent_path.exists():
        _agent_path.unlink()
    os.system("npm run build")

    if not _agent_path.exists():
        raise RuntimeError("frida-compile agent.js error")


def remove_agent_js():
    _agent_path = Path("_agent.js")
    if _agent_path.exists():
        _agent_path.unlink()


if __name__ == "__main__":
    build_agent_js()

    curdir = Path(sys.argv[0]).parent

    libQBDI = curdir / "QBDI" / "libQBDI.so"

    frida_qbdi_js = curdir / "QBDI" / "frida-qbdi.js"

    device: frida.core.Device = frida.get_usb_device()
    if not device:
        device = frida.get_remote_device()
        sys.exit(1)
    application = device.get_frontmost_application()
    if not application:
        print("No frontmost application running")
        sys.exit(1)
    print(application.name,end=" ")
    pid = application.pid
    print(f" PID: {pid}")
    session: frida.core.Session = device.attach(pid)

    script = session.create_script(read_agent_js_source())

    script.on("message", on_message)
    try:
        script.load()

    except Exception as e:
        print(f"Error loading script: {e}")
        sys.exit(1)
    # 判断exports_sync是否存在
    if not hasattr(script.exports_sync, "getfilesdir"):
        print("exports_sync not found in script")
        sys.exit(1)
    # 判断frida-qbdi.js是否存在
    if not Path(frida_qbdi_js).exists():
        print(f"frida-qbdi.js not found at {frida_qbdi_js}")
        sys.exit(1)
    filesdir = script.exports_sync.getfilesdir()

    target_so_path = Path(filesdir) / "libQBDI.so"
    if not script.exports_sync.checksoexist(target_so_path):
        with open(libQBDI, "rb") as f:
            so_buffer = f.read()
            script.exports_sync.wriatelibqbdiso(target_so_path, list(so_buffer))

    log_path = Path(filesdir) / "trace.log"
    script.exports_sync.vmrun(log_path)

    remove_agent_js()
